<template>
  <div class="calendar">
    <!-- 年月 -->
    <div class="head">
      <div>
        <span @click="setYear(false)">&lt;&lt;</span>
        <span style="margin-left: 17px" @click="setMonth(false)">&lt; </span>
      </div>
      <div>{{ date.year }} 年 {{ date.month }} 月</div>
      <div>
        <span style="margin-right: 17px" @click="setMonth(true)">&gt; </span>
        <span @click="setYear(true)">&gt;&gt;</span>
      </div>
    </div>
    <!-- 星期 -->
    <div class="weeks">
      <ul>
        <li v-for="(item, index) of weeks" :key="index">{{ item }}</li>
      </ul>
    </div>
    <!-- 日 -->
    <div class="days">
      <ul>
        <li v-for="(item, index) of days" :key="index" :class="{ ash: item.cls }">{{ item.val }}</li>
      </ul>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      date: {
        year: '',
        month: ''
      },
      weeks: ['日', '一', '二', '三', '四', '五', '六'],
      days: []
    }
  },
  methods: {
    // 获取年、月
    getDate() {
      let date = new Date()
      this.date.year = date.getFullYear()
      this.date.month = date.getMonth() + 1
      this.getViewDays()
    },
    // 获取界面中显示的天
    getViewDays() {
      let oneDayWeek = new Date(`${this.date.year}-${this.date.month}-01`).getDay()
      let lastMonth = this.date.month - 1 > 0 ? this.date.month - 1 : 12
      // 获取上月天数
      let lastMonthDays = this.getDays(lastMonth)
      this.days = []
      // 补齐上月天数
      for (let i = 0; i < oneDayWeek; i++) {
        this.days.push({
          val: lastMonthDays - oneDayWeek + i + 1,
          cls: true
        })
      }

      let thisMonthDays = this.getDays(this.date.month)
      // 放入这月天数
      for (let i = 1; i <= thisMonthDays; i++) {
        this.days.push({
          val: i
        })
      }

      // 下月天数补齐
      let nextMonthDay = 42 - this.days.length
      for (let i = 1; i <= nextMonthDay; i++) {
        this.days.push({
          val: i,
          cls: true
        })
      }
    },
    // 年份更改
    setYear(state) {
      if (state) {
        this.date.year++
      } else {
        this.date.year--
      }
      this.getViewDays()
    },
    // 月份更改
    setMonth(state) {
      if (state) {
        if (this.date.month == 12) {
          this.date.year++
          this.date.month = 1
        } else {
          this.date.month++
        }
      } else {
        if (this.date.month == 1) {
          this.date.year--
          this.date.month = 12
        } else {
          this.date.month--
        }
      }
      this.getViewDays()
    },
    // 获取一个月有多少天
    getDays(month) {
      if ([1, 3, 5, 7, 8, 10, 12].indexOf(month) != -1) {
        return 31
      } else if ([4, 6, 9, 11].indexOf(month) != -1) {
        return 30
      } else {
        if ((this.date.year % 4 === 0 && this.date.year % 100 != 0) || this.date.year % 400 == 0) {
          return 29
        } else {
          return 28
        }
      }
    }
  },
  mounted() {
    this.getDate()
  }
}
</script>

<style lang="less" scoped>
.calendar {
  width: 380px;
  box-shadow: 0px 0px 3px #ccc;
  margin: 0 auto;
  margin-top: 30px;
  border-radius: 5px;
  padding: 15px 25px;
  .head {
    display: flex;
    justify-content: space-between;
    span {
      cursor: pointer;
    }
  }
  .weeks > ul {
    display: flex;
    justify-content: space-around;
    border-bottom: 1px solid #ccc;
    padding: 10px 0;
    font-size: 13px;
    margin-top: 20px;
  }
  .days > ul {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    li {
      width: 54px;
      height: 40px;
      line-height: 40px;
      text-align: center;
    }
    .ash {
      color: #ccc;
    }
  }
}
</style>
